/**********************************************************
 * PendingAccountsAction.java.java
 * Created by Ashutosh
 * Last modified Date: Nov 18, 2008 10:49:01 AM by Nishan
 * Revision: <svn revision #>
 * Version : 0.1
 * Copyright (c) 2008 - 2009 cyberThink Infotech Pvt. Ltd., All rights reserved.
 **********************************************************/

package com.printeverywhere.action;

import static com.printeverywhere.util.AttributeConstants.CITY;
import static com.printeverywhere.util.AttributeConstants.COMPANY;
import static com.printeverywhere.util.AttributeConstants.EMAIL;
import static com.printeverywhere.util.AttributeConstants.FIRSTNAME;
import static com.printeverywhere.util.AttributeConstants.LASTNAME;
import static com.printeverywhere.util.AttributeConstants.OTHER;
import static com.printeverywhere.util.AttributeConstants.PHONE;
import static com.printeverywhere.util.AttributeConstants.STATE;
import static com.printeverywhere.util.AttributeConstants.STREET;
import static com.printeverywhere.util.AttributeConstants.USER_ID;
import static com.printeverywhere.util.AttributeConstants.WEBSITEADDRESS;
import static com.printeverywhere.util.AttributeConstants.ZIP;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import com.printeverywhere.delegator.CommonFunctionDelegator;
import com.printeverywhere.delegator.UserAccountsDelegator;
import com.printeverywhere.delegator.UserServiceDelegator;
import com.printeverywhere.dto.AccountManagerOption;
import com.printeverywhere.dto.Deposits;
import com.printeverywhere.dto.LocationCategoriesWOS;
import com.printeverywhere.dto.PendingAccounts;
import com.printeverywhere.dto.User;
import com.printeverywhere.dto.UsersInfo;
import com.printeverywhere.util.DateUtil;
import com.printeverywhere.util.DisplayConstants;
import com.printeverywhere.util.SearchCriteria;

/**
 * The Class PendingAccountsAction.
 */
public class PendingAccountsAction extends AdminEngineManagement implements ServletRequestAware {

	/** Logger for this class. */
	private static final Logger logger = Logger.getLogger(PendingAccountsAction.class);

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;

	/** The account search list. */
	private List<AccountManagerOption> accountSearchList;

	private double creditAmount;

	private double debitAmount;

	private String creditReason;

	private String debitReason;

	private UsersInfo usersInfo;

	/** The operation. */
	private String operation;

	/** The search string. */
	private String searchString;

	/** The list. */
	private List<User> list = new ArrayList<User>();

	/** The group. */
	private String group;

	/** The criteria. */
	private String criteria;

	/** The user accounts count. */
	PendingAccounts pendingAccountsCount;

	/** The selected user deleted. */
	private String[] selectedUserDeleted;

	/** The request. */
	private HttpServletRequest request;

	private int accountDetailid;

	private User accountDetailList;

	private User activeUser;

	private String deleteId = null;

	private List<Deposits> depositsList = new ArrayList<Deposits>();

	/**
	 * @return the accountDetailList
	 */
	public User getAccountDetailList() {
		return accountDetailList;
	}

	/**
	 * @param accountDetailList the accountDetailList to set
	 */
	public void setAccountDetailList(User accountDetailList) {
		this.accountDetailList = accountDetailList;
	}

	/**
	 * @return the accountDetailid
	 */
	public int getAccountDetailid() {
		return accountDetailid;
	}

	/**
	 * @param accountDetailid the accountDetailid to set
	 */
	public void setAccountDetailid(int accountDetailid) {
		this.accountDetailid = accountDetailid;
	}

	/* (non-Javadoc)
	 * @see com.opensymphony.xwork2.ActionSupport#execute()
	 */
	public String execute() throws Exception{
		if (logger.isDebugEnabled()) {
			logger.debug("execute() - start"); //$NON-NLS-1$
		}

		populateAccountSearchList();

		if (logger.isDebugEnabled()) {
			logger.debug("execute() - end"); //$NON-NLS-1$
		}
		return SUCCESS;
	}

	public String searchUser() throws Exception{

		populateAccountSearchList();
		return SUCCESS;
	}

	public String activeUser() throws Exception{

		populateAccountSearchList();

		if(request.getParameter("active") != null && request.getParameter("delete") != null){
				addActionError("One time you can Perform only one action");
				return INPUT;
			}
			if (request.getParameter("active") != null) {
				String[] checkedId = request.getParameterValues("active");
				for (String chkid : checkedId) {
					activeUser = UserServiceDelegator.getUser(Integer.parseInt(chkid));
					activeUser.setActive(true);
					activeUser.setActivationKey(null);
					UserServiceDelegator.updateUser(activeUser);
				}
				populateAccountSearchList();
				return SUCCESS;
			}else if(request.getParameter("delete") != null){
				String[] deleteCheckedId = request.getParameterValues("delete");
				for (String chkid : deleteCheckedId) {
					try{
						SearchCriteria searchCriteria=new SearchCriteria();
						searchCriteria.setAttribute("id", Integer.parseInt(chkid));
						List<User> users = UserServiceDelegator.getList(searchCriteria);
						if(users!=null && users.size()>0)
						CommonFunctionDelegator.GeneralDelete(users.get(0));
					}catch (Exception e) {
						addActionError("unable to delete user. ");
						return INPUT;
					}
				}
				addActionMessage("User deleted successfully ");
				populateAccountSearchList();
				return SUCCESS;
			}


		addActionError("Please select check box for enable or delete Pending Accounts");
		return INPUT;
	}

	/**
	 * Populate account search list.
	 */
	public void populateAccountSearchList(){
		if (logger.isDebugEnabled()) {
			logger.debug("populateAccountSearchList() - start"); //$NON-NLS-1$
		}

		accountSearchList = new ArrayList<AccountManagerOption>();
		accountSearchList.add(new AccountManagerOption(USER_ID,DisplayConstants.ACCOUNT));
		accountSearchList.add(new AccountManagerOption(EMAIL,DisplayConstants.EMAIL));
		accountSearchList.add(new AccountManagerOption(WEBSITEADDRESS,DisplayConstants.WEBSITE));
		accountSearchList.add(new AccountManagerOption(PHONE,DisplayConstants.PHONE));
		accountSearchList.add(new AccountManagerOption(FIRSTNAME,DisplayConstants.FIRST_NAME));
		accountSearchList.add(new AccountManagerOption(LASTNAME,DisplayConstants.LAST_NAME));
		accountSearchList.add(new AccountManagerOption(COMPANY,DisplayConstants.COMPANY));
		accountSearchList.add(new AccountManagerOption(STREET,DisplayConstants.STREET));
		accountSearchList.add(new AccountManagerOption(CITY,DisplayConstants.CITY));
		accountSearchList.add(new AccountManagerOption(STATE,DisplayConstants.STATE));
		accountSearchList.add(new AccountManagerOption(ZIP,DisplayConstants.ZIP));

		SearchCriteria searchCriteria = new SearchCriteria();
		searchCriteria.setAttribute("activationKey", "");
		if(operation != null){
			if(criteria.equalsIgnoreCase("state")){
				List<Criterion> criterionList = new ArrayList<Criterion>();
				criterionList.add(Restrictions.like("categoryName", searchString));
				List<LocationCategoriesWOS> categories = (List<LocationCategoriesWOS>) CommonFunctionDelegator.getObjectsByCriterion(criterionList,null,null, LocationCategoriesWOS.class);
				if(categories.size() > 0){
					searchCriteria.removeAllAttribute();
					searchCriteria.setAttribute("state.categoryId", categories.get(0).getCategoryId());
					searchCriteria.setAttribute("activationKey", "");
					list = (List<User>) CommonFunctionDelegator.GeneralgetCriteriaList(User.class.getName(), searchCriteria);
				}
			}else{
				searchCriteria.setAttribute(criteria, searchString);
				list = UserServiceDelegator.getCaseInsensitiveListOfSearch(searchCriteria);
			}
		}else if(group != null && !group.equals(OTHER)){
			searchCriteria.setAttribute(USER_ID, group);
			list = UserServiceDelegator.getCaseInsensitiveList(searchCriteria);
		}else if(group != null && group.equals(OTHER)){
			List<User> otherUser = UserServiceDelegator.getCaseInsensitiveList(searchCriteria);
			if(otherUser != null){
				Pattern pattern = null;
				pattern = Pattern.compile("^[\\-._0-9]+[a-zA-Z0-9\\-._]*");
				for (int i = 0; i < otherUser.size(); i++) {
					User user = otherUser.get(i);
					Matcher fit = pattern.matcher(user.getUserId());
					if(fit.matches()){
						list.add(user);
					}

				}
			}
		}else{
			list = UserServiceDelegator.getCaseInsensitiveList(searchCriteria);
		}
		request.getSession().setAttribute("sendConfirmationMail", list);
		pendingAccountsCount = UserAccountsDelegator.findPendingAccounts();
		if(selectedUserDeleted != null && selectedUserDeleted.length>0){
			for (String user : selectedUserDeleted) {
				// TODO TO DELETE ALL SELECTED USERS
			}
		}

		if (logger.isDebugEnabled()) {
			logger.debug("populateAccountSearchList() - end"); //$NON-NLS-1$
		}
	}

	public String accountDetails() throws Exception{
		if(request.getParameter("accountDetailid") != null) {
			accountDetailid = Integer.parseInt(request.getParameter("accountDetailid"));
			accountDetailList = UserServiceDelegator.getUser(accountDetailid);

			this.usersInfo = (UsersInfo) CommonFunctionDelegator.getObjectById("user.id", accountDetailList.getId(), UsersInfo.class);
		}
		return SUCCESS;
	}

	public String updateAccountDetails() throws Exception{
		this.usersInfo.setUser(UserServiceDelegator.getUser(this.accountDetailid));
		CommonFunctionDelegator.generalUpdatebyobj(this.usersInfo);

		if(this.creditAmount != 0) {
			Deposits deposits = new Deposits();
			deposits.setAmount(this.creditAmount);
			deposits.setDepositDate(DateUtil.getTodaysDate());
			deposits.setSource(creditReason);
			deposits.setUser(this.usersInfo.getUser());
			CommonFunctionDelegator.generalInsertbyobj(deposits);
			this.usersInfo.getUser().setCurrentBalance(this.usersInfo.getUser().getCurrentBalance() + this.creditAmount);
			CommonFunctionDelegator.generalUpdatebyobj(this.usersInfo.getUser());
		}
		if(this.debitAmount != 0) {
			Deposits deposits = new Deposits();
			deposits.setAmount(this.debitAmount);
			deposits.setDepositDate(DateUtil.getTodaysDate());
			deposits.setSource(debitReason);
			deposits.setUser(this.usersInfo.getUser());
			CommonFunctionDelegator.generalInsertbyobj(deposits);
			this.usersInfo.getUser().setCurrentBalance(this.usersInfo.getUser().getCurrentBalance() + this.debitAmount);
			CommonFunctionDelegator.generalUpdatebyobj(this.usersInfo.getUser());
		}

		return SUCCESS;
	}

	public String viewAccountSheet() {
		if(request.getParameter("accountDetailid") != null) {
			accountDetailList = UserServiceDelegator.getUser(Integer.parseInt(request.getParameter("accountDetailid")));
			SearchCriteria searchCriteria = new SearchCriteria();
			searchCriteria.setAttribute("user", accountDetailList);
			depositsList = (List<Deposits>) CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, Deposits.class);
		}
		return SUCCESS;
	}

	public String searchAccountSheet() {
		try {
			if(request.getParameter("userId") != null) {
				SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
				Date fromDate = simpleDateFormat.parse(request.getParameter("fromDate").substring(0, 10));
				Date toDate = simpleDateFormat.parse(request.getParameter("toDate").substring(0, 10));

				accountDetailList = UserServiceDelegator.getUser(Integer.parseInt(request.getParameter("userId")));
				List<Criterion> criterionList = new ArrayList<Criterion>();
				criterionList.add(Restrictions.ge("depositDate", fromDate));
				criterionList.add(Restrictions.le("depositDate", toDate));
				depositsList = (List<Deposits>) CommonFunctionDelegator.getObjectsByCriterion(criterionList, null, null, Deposits.class);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return SUCCESS;
	}

	/**
	 * @return the accountSearchList
	 */
	public List<AccountManagerOption> getAccountSearchList() {
		return accountSearchList;
	}

	/**
	 * @param accountSearchList the accountSearchList to set
	 */
	public void setAccountSearchList(List<AccountManagerOption> accountSearchList) {
		this.accountSearchList = accountSearchList;
	}

	/**
	 * @return the operation
	 */
	public String getOperation() {
		return operation;
	}

	/**
	 * @param operation the operation to set
	 */
	public void setOperation(String operation) {
		this.operation = operation;
	}

	/**
	 * @return the searchString
	 */
	public String getSearchString() {
		return searchString;
	}

	/**
	 * @param searchString the searchString to set
	 */
	public void setSearchString(String searchString) {
		this.searchString = searchString;
	}

	/**
	 * @return the list
	 */
	public List<User> getList() {
		return list;
	}

	/**
	 * @param list the list to set
	 */
	public void setList(List<User> list) {
		this.list = list;
	}

	/**
	 * @return the group
	 */
	public String getGroup() {
		return group;
	}

	/**
	 * @param group the group to set
	 */
	public void setGroup(String group) {
		this.group = group;
	}

	/**
	 * @return the criteria
	 */
	public String getCriteria() {
		return criteria;
	}

	/**
	 * @param criteria the criteria to set
	 */
	public void setCriteria(String criteria) {
		this.criteria = criteria;
	}


	public PendingAccounts getPendingAccountsCount() {
		return pendingAccountsCount;
	}

	public void setPendingAccountsCount(PendingAccounts pendingAccountsCount) {
		this.pendingAccountsCount = pendingAccountsCount;
	}

	/**
	 * @return the selectedUserDeleted
	 */
	public String[] getSelectedUserDeleted() {
		return selectedUserDeleted;
	}

	/**
	 * @param selectedUserDeleted the selectedUserDeleted to set
	 */
	public void setSelectedUserDeleted(String[] selectedUserDeleted) {
		this.selectedUserDeleted = selectedUserDeleted;
	}

	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	public User getActiveUser() {
		return activeUser;
	}

	public void setActiveUser(User activeUser) {
		this.activeUser = activeUser;
	}

	public String getDeleteId() {
		return deleteId;
	}

	public void setDeleteId(String deleteId) {
		this.deleteId = deleteId;
	}

	public UsersInfo getUsersInfo() {
		return usersInfo;
	}

	public void setUsersInfo(UsersInfo usersInfo) {
		this.usersInfo = usersInfo;
	}

	public void setCreditAmount(double creditAmount) {
		this.creditAmount = creditAmount;
	}

	public void setDebitAmount(double debitAmount) {
		this.debitAmount = debitAmount;
	}

	public void setCreditReason(String creditReason) {
		this.creditReason = creditReason;
	}

	public void setDebitReason(String debitReason) {
		this.debitReason = debitReason;
	}

	public List<Deposits> getDepositsList() {
		return depositsList;
	}


}